/**
 *
 */
package de.cbf.cam.dsa.rcp.model.entities;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlElementWrapper;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import de.cbf.util.uuidheader.entities.UUIDHeader;
import de.cbf.util.uuidheader.exceptions.EntityMergeException;

/**
 * @author salter
 */
@XmlAccessorType(XmlAccessType.FIELD)
public class CultureNameData extends UUIDHeader implements Cloneable{

	private static final Log logger = LogFactory.getLog(CultureNameData.class);

	protected Map<String, NameList> namesMap ;
	@XmlElementWrapper(name="formats")
	@XmlElement(name="format")
	protected List<NameFormat> formats;


	/**
	 *
	 */
	public CultureNameData() {
		namesMap = new HashMap<String, NameList>();
		formats = new ArrayList<NameFormat>();
	}

	@Override
	protected void doMergeDataFrom(UUIDHeader entity, boolean i_am_older)
			throws EntityMergeException {
		if (entity instanceof CultureNameData) {
			CultureNameData other = (CultureNameData) entity;
			if(i_am_older){
				this.namesMap.clear();
				this.namesMap.putAll(namesMap);
				this.formats.clear();
				this.formats.addAll(other.formats);
			}
		}else{
			throw new EntityMergeException("Entity does not fit class");
		}
	}

	@Override
	public Object clone() throws CloneNotSupportedException {
		CultureNameData clone = new CultureNameData();
		try {
			clone.mergeDataFrom(this);
		} catch (EntityMergeException e) {
			throw new CloneNotSupportedException(e.getLocalizedMessage());
		}
		return clone;
	}
	@Override
	public int hashCode() {
		final int prime = 31;
		int result = super.hashCode();
		result = prime * result + ((formats == null) ? 0 : formats.hashCode());
		result = prime * result
				+ ((namesMap == null) ? 0 : namesMap.hashCode());
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (!super.equals(obj))
			return false;
		if (getClass() != obj.getClass())
			return false;
		CultureNameData other = (CultureNameData) obj;
		if (formats == null) {
			if (other.formats != null)
				return false;
		} else if (!formats.equals(other.formats))
			return false;
		if (namesMap == null) {
			if (other.namesMap != null)
				return false;
		} else if (!namesMap.equals(other.namesMap))
			return false;
		return true;
	}

	public Map<String, NameList> getNamesMap() {
		return namesMap;
	}

	public NameList getNamesByKey(String key){
		return namesMap.get(key);
	}

	public void addNamesToKey(String key,List<String> names ){
		NameList alreadyPresent =  namesMap.get(key);
		if(alreadyPresent != null){
			logger.warn("names key "+key+" is already present, replacing");
			alreadyPresent.getNames().clear();
			alreadyPresent.addNames(names);
		}else{
			alreadyPresent = new NameList();
			alreadyPresent.addNames(names);
		}
		namesMap.put(key, alreadyPresent);
	}

	public void setNamesMap(Map<String, NameList> namesMap) {
		this.namesMap = namesMap;
	}


	public List<NameFormat> getFormats() {
		return formats;
	}

	public boolean addFormat(NameFormat format){
		return formats.add(format);
	}

	public boolean removeFormat(NameFormat format){
		return formats.remove(format);
	}

	public void setFormats(List<NameFormat> formats) {
		this.formats.clear();
		this.formats.addAll(formats);
	}












}
